﻿using System;
using System.Collections.Generic;
using System.Data;
using System.Data.Entity;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using ScrumProject.Models;
using ScrumProject.ViewModels;

namespace ScrumProject.Controllers
{
    public class TaskController : Controller
    {
        private SMRPO6Context db = new SMRPO6Context();
        TaskRepository taskR = new TaskRepository();
        RealizedWorkRepository rwr = new RealizedWorkRepository();
        WorkMeasyrementRepository wmr = new WorkMeasyrementRepository();
        //
        // GET: /Task/

        public ActionResult Index(int storyId)
        {
            var tasks = db.Tasks.Include(t => t.Story.Id);
            ViewBag.storyId = storyId;

            StoryRepository sr = new StoryRepository();
            Story s = sr.GetStory(storyId);
            ViewBag.storyName = s.Name;
            ViewBag.projectId = s.ProjectId;

            return View(taskR.GetTasksByStory(storyId));

        }

        //
        // GET: /Task/Details/5

        public ActionResult Details(int id)
        {
            Task task = db.Tasks.Find(id);
            ViewBag.storyId = task.StoryId;
            return View(task);
        }

        //
        // GET: /Task/Create

        public ActionResult Create(int storyId)
        {
            ViewBag.StoryId = new SelectList(db.Stories, "Id", "Name");
            ViewBag.newId = storyId;

            StoryRepository sr = new StoryRepository();
            Story s = sr.GetStory(storyId);
            ViewBag.projectId = s.ProjectId;

            return View();
        } 

        //
        // POST: /Task/Create

        [HttpPost]
        public ActionResult Create(Task task)
        {
            StoryRepository sr = new StoryRepository();
            Story st = sr.GetStory((int)task.StoryId);
            ViewBag.projectId = st.ProjectId;

            
                if (task.UserId == null) 
                    task.UserId = -1;
                if (task.WorkRemaining == null)
                    task.WorkRemaining = 0.0;

                ViewBag.projectId = st.ProjectId;

                db.Tasks.Add(task);
                db.SaveChanges();
                //taskR.AddTask(task);
                return RedirectToAction("Index", new { storyId = task.StoryId });
            
        }
        
        //
        // GET: /Task/Edit/5
 
        public ActionResult Edit(int id)
        {
            Task task = db.Tasks.Find(id);
            ViewBag.StoryId = new SelectList(db.Stories, "Id", "Name", task.StoryId);
            ViewBag.newId = task.StoryId;

            StoryRepository sr = new StoryRepository();
            Story s = sr.GetStory((int)task.StoryId);
            ViewBag.projectId = s.ProjectId;

            return View(task);
        }

        //
        // POST: /Task/Edit/5

        [HttpPost]
        public ActionResult Edit(Task task)
        {
            if (ModelState.IsValid)
            {
                Task t = taskR.GetTask(task.Id);
                if (task.Description == null)
                    task.Description = t.Description;
                if (task.StoryId == null)
                    task.StoryId = t.StoryId;
                if (task.Story == null)
                    task.Story = t.Story;
                if (task.WorkRemaining == null)
                    task.WorkRemaining = t.WorkRemaining;
                if (task.UserId == null)
                    task.UserId = t.UserId;

                StoryRepository sr = new StoryRepository();
                Story st = sr.GetStory((int)task.StoryId);
                               
                taskR.UpdateTask(task);
                return RedirectToAction("Index", new { storyId = task.StoryId });
                
            }
            ViewBag.newId = task.StoryId;
            ViewBag.StoryId = new SelectList(db.Stories, "Id", "Name", task.StoryId);
            return View(task);
        }

        //
        // GET: /Task/Delete/5
 
        public ActionResult Delete(int id)
        {
            Task task = db.Tasks.Find(id);
            ViewBag.storyId = task.StoryId;
            return View(task);
        }

        public ActionResult MyTasks(Task task)
        {
            var posts = db.Posts.Include(p => p.Project);
            var viewModel = new TasksViewModel();

            int id = int.Parse(this.ControllerContext.HttpContext.Request.Cookies["projectId"].Value);
            viewModel.Tasks = taskR.GetTasksByUserAndProject((User as CustomPrincipal).UserId, 1, id);
            ViewBag.UserId = (User as CustomPrincipal).UserId;
            //viewModel.Tasks = taskR.GetTasksByUserAndProject((User as CustomPrincipal).UserId, 1, id);

            viewModel.Tasks = taskR.GetTasksByUserAndProject((User as CustomPrincipal).UserId, id);

            return View(viewModel);
            
            //Maja
            //String userName = (User as CustomPrincipal).Username;
            //UserRepository ur = new UserRepository();
            //User u = ur.GetByUserName(User.Identity.Name);
            //ViewBag.ViewUser = (User as CustomPrincipal).Username;
            //ViewBag.UserId = (User as CustomPrincipal).UserId;
            
            //return View();
        }

        public ActionResult AcceptTask() 
        {
            return View();
        }

        [HttpPost]
        public ActionResult AcceptTask(int taskId, string submitButton) 
        {
            Task task = taskR.GetTask(taskId);
            CustomPrincipal user = HttpContext.User as CustomPrincipal;

            if (submitButton == "Cancel")
            {
                return RedirectToAction("SprintBacklog", "MyProjects");
            }

            else
            {   
                task.Status = 1;
                task.UserId = user.UserId;
                taskR.UpdateTaskCurrentStatus(task);
            
                List<DateTime> listOfDates = new List<DateTime>();
                //DateTime today = DateTime.Now;
                DateTime earlier = DateTime.Now.AddDays(-5);
                DateTime sprintEndDate = taskR.GetSprintEndDate(task);
                List<RealizedWork> rwList = rwr.getRealizedWorksByTaskAndUser(task.Id, user.UserId).ToList<RealizedWork>();
                if (rwList.Count.Equals(0))
                {
                    do
                    {
                        listOfDates.Add(earlier);
                        earlier = earlier.AddDays(1);
                    } while (earlier <= sprintEndDate);

                    for (int i = 0; i < listOfDates.Count; i++)
                    {
                        RealizedWork rw = new RealizedWork();
                        rw.DateOfWorking = listOfDates[i];
                        rw.TaskId = task.Id;
                        rw.WorkRemaining = task.WorkRemaining;
                        rw.UserId = user.UserId;
                        rwr.AddRealizedWork(rw);
                    }
                }
                else
                {
                    //List<RealizedWork> rw = rwr.getRealizedWorksByTaskAndUser(task.Id, user.UserId).ToList<RealizedWork>();
                    for (int i = 0; i < rwList.Count; i++)
                    {
                        if (rwList[i].DateOfWorking.Date.Equals(DateTime.Now.Date) || DateTime.Compare(rwList[i].DateOfWorking,DateTime.Now) > 0)
                        {
                            rwr.UpdateRealizedWorkTime(rwList[i].Id, rwList[i].WorkDone.Value, rwList[i].UserId, task.WorkRemaining);
                        }
                    }
                }

                return RedirectToAction("SprintBacklog", "MyProjects");
            }
        }

        public ActionResult ReleaseTask()
        {
            return View();
        }

        [HttpPost]
        public ActionResult ReleaseTask(int id, string submitButton)
        {
            Task task = taskR.GetTask(id);
            
            if (submitButton == "Cancel")
            {
                return RedirectToAction("MyTasks");
            }

            else
            {
                task.Status = 2;
                task.UserId = -1;
                taskR.UpdateTaskCurrentStatus(task);

                return RedirectToAction("MyTasks");
            }
        }


        //
        // POST: /Task/Delete/5

        [HttpPost, ActionName("Delete")]
        public ActionResult DeleteConfirmed(int id)
        {
            Task task = db.Tasks.Find(id);
            int pid = (int)task.StoryId;
            db.Tasks.Remove(task);
            db.SaveChanges();
            return RedirectToAction("Index", new { storyId = pid });
        }

        public ActionResult WorkHistory(int? id)
        {
           
            Task task = db.Tasks.Find(id);
            
            ViewBag.taskId = task.Id;
            return View(task);
        }

        [HttpPost]
        public ActionResult WorkHistory(Task wh)
        {
             return RedirectToAction("MyTasks");
            
        }

        public ActionResult WorkDoneUpdate(List<WorkDoneItem> ListComp)
        {
            CustomPrincipal user = HttpContext.User as CustomPrincipal;
            
            foreach (WorkDoneItem w in ListComp)
            {
                rwr.UpdateRealizedWorkTime(w.id, w.itemTime, user.UserId, w.workRemaining);
            }

            taskR.UpdateTaskRemainingWork(ListComp[0].taskId, ListComp[ListComp.Count-1].workRemaining);

            Task t = taskR.GetTask(ListComp[0].taskId);

            if (ListComp[ListComp.Count - 1].workRemaining != 0.0)
                t.Status = 1;
             
            else if (ListComp[ListComp.Count - 1].workRemaining == 0.0) 
                t.Status=3;

            taskR.UpdateTaskCurrentStatus(t);
            
            return RedirectToAction("MyTasks");
        }

        public void MeasureWork(WorkMeasurement w)
        {
            CustomPrincipal user = HttpContext.User as CustomPrincipal;
            int v2 = 0;
            if (w.id.HasValue)
                v2 = w.id.Value;
            List<RealizedWork> dt = rwr.getRealizedWorksByTask(v2).ToList<RealizedWork>();
            //TimeSpan span = w.endTime.Subtract ( w.startTime );
            DateTime d1 = DateTime.Now;
            DateTime d2 = DateTime.Now;
            if (w.endTime.HasValue) d2 = w.endTime.Value;
            if (w.startTime.HasValue) d1 = w.startTime.Value;
            double span = (d2 - d1).TotalHours;
            for (int i = 0; i < dt.Count; i++)
            {
                if (dt[i].DateOfWorking.Date.Equals(DateTime.Now.Date))
                {
                    double wr = 0;
                    if (dt[i].WorkRemaining.HasValue) wr = dt[i].WorkRemaining.Value;
                    rwr.UpdateRealizedWorkTime(dt[i].Id, Math.Round(span, 5),user.UserId, Math.Round((wr - span), 5));
                    taskR.UpdateTaskRemainingWork(v2, Math.Round((wr - span), 5));
                    if ((wr - span) == 0.0)
                    {
                        Task t = taskR.GetTask(v2);
                        t.Status = 3;
                        taskR.UpdateTaskStatus(t);
                    }
                    else
                    {
                        Task t = taskR.GetTask(v2);
                        t.Status = 1;
                        taskR.UpdateTaskStatus(t);
                    }
                    break;

                }

            }
        }

        [HttpPost]
        public ActionResult MeasureWorkBegin(Work ww)
        {
            CustomPrincipal user = HttpContext.User as CustomPrincipal;
            if (wmr.GetMeasurementByUser(user.UserId) != null)
            {
                WorkMeasurement wm = new WorkMeasurement();
                wm = (wmr.GetMeasurementByUser(user.UserId));
                if (wm.startTime != null)
                {
                    return Json("show");
                }
                else
                {
                    return Json("hide");
                }

            }

            return Json("hide");
        }
      
        [HttpPost]
        public ActionResult MeasureWorkStart(Work w)
        {
            CustomPrincipal user = HttpContext.User as CustomPrincipal;
            
            
            if (wmr.GetMeasurementByUser(user.UserId) != null)
            {
                WorkMeasurement wm = new WorkMeasurement();
                wm=(wmr.GetMeasurementByUser(user.UserId));
                if(wm.startTime!=null){
                    return Json("bad");
                }
                else{
                
                    wm.startTime=w.startTime;
                    wm.id = w.id;
                    db.Entry(wm).State= EntityState.Modified;
                    db.SaveChanges();
                }

            }
            else {
                WorkMeasurement wm = new WorkMeasurement();
                wm.startTime = w.startTime;
                wm.id = w.id;
                wm.userId = user.UserId;
                db.WorkMeasurements.Add(wm);
                db.SaveChanges();
                
            }

            return Json("ok");
        }
        [HttpPost]
        public ActionResult MeasureWorkStop(Work w)
        {

            CustomPrincipal user = HttpContext.User as CustomPrincipal;
            WorkMeasurement wm = wmr.GetMeasurementByUser(user.UserId);
            if (wm != null)
            {
                if (wm.startTime != null)
                {
                    wm.endTime = w.endTime;
                    db.Entry(wm).State = EntityState.Modified;
                    db.SaveChanges();
                    MeasureWork(wm);
                    wm.endTime = null;
                    wm.startTime = null;
                    db.Entry(wm).State = EntityState.Modified;
                    db.SaveChanges();

                }
               
            }

            return Json("ok");
        }

        protected override void Dispose(bool disposing)
        {
            db.Dispose();
            base.Dispose(disposing);
        }
    }
}
